import React, { ReactElement } from 'react';
import { View, Keyboard } from 'react-native';
import Picker from 'react-native-picker';
import { clone, trim } from 'ramda';

import { Dispatch, Province, City, State, AddressProps } from './types';
import navigator from '../../util/navigator';
import { UserApi, CommonApi } from '../../api';
import { toolTipOpen, modalOpen, modalClose } from '../../util/global';
import { phonePx } from '../../util/adapt';
import {
  needUpdateDistrictInfo,
  getDistrictInfo,
  setDistrictData
} from '../../store/address';
import { ProvinceInfo as ProvinceData } from '../../api/common/getDistrictInfo';
import PortraitAlert from '../../components/Alert/PortraitAlert';

let dispatch: Dispatch;
let state: State;

let provinceInfo: Province[] = [];

let originAddress: AddressProps = {
  receiverName: '',
  receiverMobilePhone: '',
  detail: '',
  districtInfo: []
};

export default (d: Dispatch, s: State): void => {
  dispatch = d;
  state = s;
};

export const fetchFailed = (): void => {
  dispatch({ type: 'FETCH_FAILED' });
};

export const setReceiverName = (value: string): void => {
  dispatch({ type: 'SET_RECEIVER_NAME', value });
};

export const setReceiverPhone = (value: string): void => {
  dispatch({ type: 'SET_RECEIVER_PHONE', value });
};

export const setDetailAddress = (value: string): void => {
  dispatch({ type: 'SET_DETAIL_ADDRESS', value });
};

export const setDistrictInfo = (value: string[]): void => {
  dispatch({ type: 'SET_DISTRICT_INFO', value });
};

export const initInfo = (value: AddressProps): void => {
  if (value && value.receiverMobilePhone && value.districtInfo.length > 0) {
    originAddress = clone(value);
    dispatch({ type: 'INIT_INFO', value });
  }
};

// 获取数据
export const getAddress = (): void => {
  UserApi.getUserAddress().then((res): void => {
    if (res.code === 0) {
      const {
        province,
        city,
        district,
        detail,
        receiverName,
        receiverMobilePhone
      } = res.data;

      initInfo({
        receiverName,
        receiverMobilePhone,
        detail,
        districtInfo: [province, city, district]
      });
    }
  });
};

// 返回
export const back = (): void => {
  Picker.hide();
  modalClose();

  navigator.goBack();
};

export const backAlert = (): void => {
  Keyboard.dismiss();

  const { isFetchFailed, ...address } = state;
  if (JSON.stringify(address) === JSON.stringify(originAddress)) {
    back();
    return;
  }

  modalOpen({
    Type: (): React.ReactElement => (
      <PortraitAlert
        title="确认返回吗"
        subTitle="填写内容未保存，返回填写内容将会丢失。"
        sureDesc="确认"
        cancelDesc="取消"
        cancelAction={(): void => {
          modalClose();
        }}
        sureAction={back}
      />
    ),
    needBack: true
  });
};

export const initPicker = (): void => {
  const { districtInfo } = state;
  Picker.init({
    pickerData: provinceInfo,
    pickerBg: [255, 255, 255, 1],
    selectedValue: districtInfo,
    pickerToolBarBg: [255, 255, 255, 1],
    pickerCancelBtnColor: [155, 155, 155, 1],
    pickerConfirmBtnColor: [60, 150, 250, 1],
    pickerToolBarFontSize: phonePx(14),
    pickerCancelBtnText: '取消',
    pickerConfirmBtnText: '确定',
    pickerTitleText: '',
    onPickerConfirm: (data): void => {
      setDistrictInfo(data);
      modalClose();
    },
    onPickerCancel: (): void => {
      modalClose();
    },
    onPickerSelect: (): void => {}
  });
};

export const showPicker = (): void => {
  initPicker();
  modalOpen({
    Type: (): React.ReactElement => <View />,
    needBack: true,
    closeAction: (): void => {
      Picker.hide();
      modalClose();
    },
    needClose: true
  });
  Picker.show();
};

const change = (provinces: ProvinceData[]): Province[] =>
  provinces.map(
    (item): Province => ({
      [item.provinceName]:
        item.cities && item.cities.length > 0
          ? item.cities.map(
              (city): City => ({
                [city.cityName]:
                  city.districts && city.districts.length > 0
                    ? city.districts
                    : ['']
              })
            )
          : [{ '': [''] }]
    })
  );

export const getDistrict = (): void => {
  if (needUpdateDistrictInfo()) {
    CommonApi.getDistrictInfo()
      .then((res): void => {
        if (res.code === 0) {
          const { provinces = [] } = res.data;
          provinceInfo = change(provinces);
          setDistrictData(res);
        } else {
          const { provinces = [] } = getDistrictInfo().data;
          provinceInfo = change(provinces);
        }
      })
      .catch((): void => {
        const { provinces = [] } = getDistrictInfo().data;
        provinceInfo = change(provinces);
      });
    const { provinces = [] } = getDistrictInfo().data;
    provinceInfo = change(provinces);
  } else {
    const { provinces = [] } = getDistrictInfo().data;
    provinceInfo = change(provinces);
  }
};

export const save = (): void => {
  const { receiverName, receiverMobilePhone, detail, districtInfo } = state;

  const params = {
    province: districtInfo.length > 0 ? districtInfo[0] : '',
    city: districtInfo.length > 1 ? districtInfo[1] : '',
    district: districtInfo.length > 2 ? districtInfo[2] : '',
    detail,
    receiverName,
    receiverMobilePhone
  };
  UserApi.saveUserAddress(params).then((res): void => {
    if (res.code === 0) {
      toolTipOpen({ desc: '保存收货地址成功' });
      back();
    }
  });
};

export const sureSave = (): void => {
  Keyboard.dismiss();
  const { receiverName, receiverMobilePhone, detail, districtInfo } = state;

  if (trim(receiverName).length === 0) {
    toolTipOpen({ desc: '收货人不能为空' });
    return;
  }

  if (
    receiverName.includes('<') ||
    receiverName.includes('>') ||
    receiverName.includes('/') ||
    receiverName.includes('script')
  ) {
    toolTipOpen({ desc: '收货人不能含有特殊字符' });
    return;
  }

  if (trim(receiverMobilePhone).length === 0) {
    toolTipOpen({ desc: '手机号不能为空' });
    return;
  }

  const phoneTest = /^(\d{11})$/;
  if (!phoneTest.test(receiverMobilePhone)) {
    toolTipOpen({ desc: '手机号格式有误' });
    return;
  }

  if (districtInfo.length === 0) {
    toolTipOpen({ desc: '省市区不能为空' });
    return;
  }

  if (trim(detail).length === 0) {
    toolTipOpen({ desc: '详细地址不能为空' });
    return;
  }

  if (
    detail.includes('<') ||
    detail.includes('>') ||
    detail.includes('/') ||
    detail.includes('script')
  ) {
    toolTipOpen({ desc: '详细地址不能含有特殊字符' });
    return;
  }

  modalOpen({
    Type: (): React.ReactElement => (
      <PortraitAlert
        title="确认收货地址"
        sureDesc="确认"
        cancelDesc="修改"
        cancelAction={modalClose}
        subTitle={`${receiverName} ${receiverMobilePhone} ${districtInfo.join(
          ' '
        )} ${detail}`}
        sureAction={(): void => {
          modalClose();
          save();
        }}
      />
    ),
    needBack: true
  });
};
